package com.tiheima.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tiheima.handler.enums.CommonExceptionEnum;
import com.tiheima.handler.exception.ExceptionCast;
import com.tiheima.manager.MinIOManager;
import com.tiheima.mapper.EmpExprMapper;
import com.tiheima.mapper.EmpMapper;
import com.tiheima.model.dos.EmpAndExprListByIdDO;
import com.tiheima.model.dos.EmpListDO;
import com.tiheima.model.dto.LoginDTO;
import com.tiheima.model.dto.emp.AddEmpDTO;
import com.tiheima.model.dto.emp.EmpAndExprListDTO;
import com.tiheima.model.dto.empExpr.EmpExprDTO;
import com.tiheima.model.dto.emp.EmpPageQuery;
import com.tiheima.model.entity.Emp;
import com.tiheima.model.entity.EmpExpr;
import com.tiheima.model.entity.EmpLog;
import com.tiheima.model.result.PageResult;
import com.tiheima.model.result.Result;
import com.tiheima.model.vo.EmpAndExprListByIdVO;
import com.tiheima.model.vo.GetEmpListVO;
import com.tiheima.model.vo.LoginVO;
import com.tiheima.service.EmpLogService;
import com.tiheima.service.EmpService;
import com.tiheima.utils.JwtUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工管理
 */
@Service
public class EmpServiceImpl implements EmpService {

    private final EmpMapper empMapper;
    private final EmpExprMapper empExprMapper;
    private final MinIOManager minIOManager;
    private final EmpLogService empLogService;

    public EmpServiceImpl(EmpMapper empMapper, EmpExprMapper empExprMapper, MinIOManager minIOManager, EmpLogService empLogService) {
        this.empMapper = empMapper;
        this.empExprMapper = empExprMapper;
        this.minIOManager = minIOManager;
        this.empLogService = empLogService;
    }

    @Override
    public PageResult<EmpListDO> getPage(EmpPageQuery query) {
        query.checkPageParam();
        PageHelper.startPage(query.getPage(), query.getPageSize());
        List<EmpListDO> list = empMapper.pageList(query);
        PageInfo<EmpListDO> pageResult = new PageInfo<>(list);
        return PageResult.of(pageResult.getTotal(), pageResult.getList());
    }

    @Transactional
    @Override
    public void deleteEmp(ArrayList<Integer> ids) {
        if (ids.isEmpty()) {
            throw new RuntimeException("参数非法");
        }
        // 在删除用户数据之前，先获取到图片地址，以便用于删除云端的图片
        ArrayList<String> images = empMapper.selectImageListByEmpIds(ids);
        // 删除员工数据，并删除关联的经历
        empMapper.deleteEmp(ids);
        // 删除已上传的图片
        minIOManager.deletes(images);
    }

    @Transactional
    @Override
    public void addEmp(AddEmpDTO dto) {
        try {
            // 1. 参数校验
            boolean flag = BeanUtil.hasNullField(dto, "job", "salary", "image", "entryDate", "deptId", "exprList");
            if (flag) {
                throw new RuntimeException("参数非法");
            }
            Emp emp = new Emp();
            // 同名属性拷贝赋值
            BeanUtil.copyProperties(dto, emp);
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            empMapper.insertEmp(emp);

            if (!dto.getExprList().isEmpty()) {
                // 获取员工工作经历列表
                List<EmpExprDTO> exprList = dto.getExprList();
                // 将员工工作经历列表  转换成员工工作经历实体类列表 List<EmpExprDTO> --->List<EmpExpr>
                List<EmpExpr> list = exprList.stream().map(empExprDto -> {
                    // 创建一个员工工作经历实体类
                    EmpExpr empExpr = new EmpExpr();
                    // DTO中数复制拷贝到 empExpr
                    BeanUtil.copyProperties(empExprDto, empExpr);
                    // 补全数据 [主键返回]
                    empExpr.setEmpId(emp.getId());
                    return empExpr;
                }).toList();
                // 批量插入数据到数据库
                empExprMapper.insertBatch(list);
            }
        } finally {
            // 记录日志
            EmpLog empLog = new EmpLog();
            empLog.setOperateTime(LocalDateTime.now());
            empLog.setInfo("添加员工：" + dto.toString());
            empLogService.insertLog(empLog);
        }
    }


    @Override
    public EmpAndExprListByIdVO getEmpAndExprListById(Integer id) {
        if (id == null) {
            throw new RuntimeException("参数非法");
        }
        // EmpAndExprListByIdVO empAndExprListByIdVO = empMapper.selectEmpAndExprListById(id);
        EmpAndExprListByIdVO empAndExprListByIdVO = empMapper.selectEmpById(id);
        if (empAndExprListByIdVO == null) {
            throw new RuntimeException("员工不存在");
        }
        List<EmpExpr> exprList = empExprMapper.selectExprListByEmpId(id);
        if (exprList != null) {
            empAndExprListByIdVO.setExprList(exprList);
        }
        return empAndExprListByIdVO;
    }

    @Transactional
    @Override
    public void updateEmpAndExpr(EmpAndExprListDTO empAndExprListDTO) {
        if (BeanUtil.hasNullField(empAndExprListDTO, "job", "salary", "image", "entryDate", "deptId", "exprList")) {
            throw new RuntimeException("参数非法");
        }
        // 获取原头像地址
        ArrayList<Integer> id = new ArrayList<>();
        id.add(empAndExprListDTO.getId());
        ArrayList<String> image = empMapper.selectImageListByEmpIds(id);
        empAndExprListDTO.setUpdateTime(LocalDateTime.now());
        empMapper.updateEmp(empAndExprListDTO);
        // 对比更新后的头像地址如果有变化则把原来的头像从云端删除
        if (!image.get(0).equals(empAndExprListDTO.getImage())) {
            ArrayList<String> list = new ArrayList<>();
            list.add(image.get(0));
            minIOManager.deletes(list);
        }
        // 删除原经历
        empExprMapper.deleteExprByEmpId(empAndExprListDTO.getId());
        // 添加新经历
        if (!empAndExprListDTO.getExprList().isEmpty()) {
            List<EmpExpr> empExprList = new ArrayList<>(empAndExprListDTO.getExprList());
            for (EmpExpr empExpr : empExprList) {
                empExpr.setEmpId(empAndExprListDTO.getId());
            }
            empExprMapper.insertBatch(empExprList);
        }
    }

    @Override
    public List<GetEmpListVO> getEmpList() {
        return empMapper.selectEmpList();
    }

    @Override
    public Result<LoginVO> login(LoginDTO loginDTO) {
        if (BeanUtil.hasNullField(loginDTO)){
            throw new RuntimeException("参数非法");
        }
        Emp emp = empMapper.selectEmpByUsernameAndPassword(loginDTO.getUsername(), loginDTO.getPassword());
        if (BeanUtil.isEmpty(emp)) {
            ExceptionCast.cast(CommonExceptionEnum.USER_PASSWORD_ERROR);
        }
        LoginVO loginVO = new LoginVO();
        BeanUtil.copyProperties(emp, loginVO);
        //@TODO token
        Map<String, Object> map = new HashMap<>();
        map.put("id", emp.getId());
        map.put("username", emp.getUsername());
        String s = JwtUtils.generateJwt(map);
        loginVO.setToken(s);
        return Result.success(loginVO);
    }
}
